#include "ConfigManager.h"
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QStandardPaths>
#include <QDir>
#include <QVariantMap>

/**
 * @brief 构造函数
 * @param parent 父对象
 */
ConfigManager::ConfigManager(QObject *parent)
    : QObject(parent)
{
    // 设置默认配置文件路径
    QString appDataPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    QDir appDataDir(appDataPath);
    if (!appDataDir.exists()) {
        appDataDir.mkpath(appDataPath);
    }
    m_configFilePath = appDataPath + "/config.json";
    
    // 添加默认配置
    addConfig(m_defaultConfigName);
}

/**
 * @brief 析构函数
 */
ConfigManager::~ConfigManager()
{
    // 析构函数
}

// ========== 配置级别的操作 ==========

/**
 * @brief 添加新的配置
 * @param configName 配置名称（唯一标识）
 * @param configParams 配置参数，键为参数名称
 */
void ConfigManager::addConfig(const QString &configName, const QVariantMap &configParams)
{
    if (!containsConfig(configName)) {
        m_configs[configName] = configParams;
        emit configAdded(configName);
    }
}

/**
 * @brief 移除指定配置
 * @param configName 配置名称（唯一标识）
 * @note 默认配置无法移除
 */
void ConfigManager::removeConfig(const QString &configName)
{
    if (containsConfig(configName) && configName != m_defaultConfigName) {
        m_configs.remove(configName);
        emit configRemoved(configName);
    }
}

/**
 * @brief 检查配置是否存在
 * @param configName 配置名称（唯一标识）
 * @return 是否存在
 */
bool ConfigManager::containsConfig(const QString &configName) const
{
    return m_configs.contains(configName);
}

/**
 * @brief 获取所有配置名称列表
 * @return 配置名称列表
 */
QStringList ConfigManager::getConfigNames() const
{
    return m_configs.keys();
}

/**
 * @brief 清除所有配置
 * @note 保留默认配置
 */
void ConfigManager::clearAllConfigs()
{
    // 保留默认配置
    QVariantMap defaultConfig = m_configs.value(m_defaultConfigName).toMap();
    m_configs.clear();
    m_configs[m_defaultConfigName] = defaultConfig;
    
    // 发射默认配置的变更信号
    emit configParamsChanged(m_defaultConfigName, defaultConfig);
}

// ========== 配置参数级别的操作 ==========

/**
 * @brief 设置配置的所有参数
 * @param configName 配置名称（唯一标识）
 * @param configParams 配置参数，键为参数名称
 */
void ConfigManager::setConfigParams(const QString &configName, const QVariantMap &configParams)
{
    if (containsConfig(configName)) {
        QVariantMap oldParams = m_configs[configName].toMap();
        m_configs[configName] = configParams;
        
        // 找出变更的参数
        QVariantMap changedParams;
        for (auto it = configParams.constBegin(); it != configParams.constEnd(); ++it) {
            const QString &paramName = it.key();
            const QVariant &value = it.value();
            if (!oldParams.contains(paramName) || oldParams[paramName] != value) {
                changedParams[paramName] = value;
            }
        }
        
        // 发射批量变更信号
        if (!changedParams.isEmpty()) {
            emit configParamsChanged(configName, changedParams);
        }
    }
    else
    {
        addConfig(configName,configParams);
    }
}

/**
 * @brief 获取配置的所有参数
 * @param configName 配置名称（唯一标识）
 * @return 配置参数，键为参数名称
 */
QVariantMap ConfigManager::getConfigParams(const QString &configName) const
{
    if (containsConfig(configName)) {
        return m_configs[configName].toMap();
    }
    return QVariantMap();
}

/**
 * @brief 获取配置的单个参数
 * @param configName 配置名称（唯一标识）
 * @param paramName 参数名称（唯一标识）
 * @param defaultValue 默认值
 * @return 参数值，如果不存在则返回默认值
 */
QVariant ConfigManager::getConfigParam(const QString &configName, const QString &paramName, 
                                      const QVariant &defaultValue) const
{
    if (containsConfig(configName)) {
        QVariantMap configParams = m_configs[configName].toMap();
        if (configParams.contains(paramName)) {
            return configParams[paramName];
        }
    }
    return defaultValue;
}

/**
 * @brief 设置配置的单个参数
 * @param configName 配置名称（唯一标识）
 * @param paramName 参数名称（唯一标识）
 * @param value 参数值
 */
void ConfigManager::setConfigParam(const QString &configName, const QString &paramName, 
                                  const QVariant &value)
{
    if (containsConfig(configName)) {
        QVariantMap configParams = m_configs[configName].toMap();
        QVariant oldValue;
        
        if (configParams.contains(paramName)) {
            oldValue = configParams[paramName];
        }
        
        // 只有当值发生变化时才更新并发射信号
        if (oldValue != value) {
            configParams[paramName] = value;
            m_configs[configName] = configParams;
            emit configParamChanged(configName, paramName, oldValue, value);
        }
    }
}

/**
 * @brief 检查配置中是否包含指定参数
 * @param configName 配置名称（唯一标识）
 * @param paramName 参数名称（唯一标识）
 * @return 是否包含
 */
bool ConfigManager::containsConfigParam(const QString &configName, const QString &paramName) const
{
    if (containsConfig(configName)) {
        QVariantMap configParams = m_configs[configName].toMap();
        return configParams.contains(paramName);
    }
    return false;
}

/**
 * @brief 移除配置中的指定参数
 * @param configName 配置名称（唯一标识）
 * @param paramName 参数名称（唯一标识）
 */
void ConfigManager::removeConfigParam(const QString &configName, const QString &paramName)
{
    if (containsConfig(configName)) {
        QVariantMap configParams = m_configs[configName].toMap();
        if (configParams.contains(paramName)) {
            QVariant oldValue = configParams[paramName];
            configParams.remove(paramName);
            m_configs[configName] = configParams;
            emit configParamChanged(configName, paramName, oldValue, QVariant());
        }
    }
}

/**
 * @brief 获取配置的所有参数名称
 * @param configName 配置名称（唯一标识）
 * @return 参数名称列表
 */
QStringList ConfigManager::getConfigParamNames(const QString &configName) const
{
    if (containsConfig(configName)) {
        QVariantMap configParams = m_configs[configName].toMap();
        return configParams.keys();
    }
    return QStringList();
}

/**
 * @brief 批量设置配置的参数
 * @param configName 配置名称（唯一标识）
 * @param configParams 配置参数，键为参数名称
 */
void ConfigManager::batchSetConfigParams(const QString &configName, const QVariantMap &configParams)
{
    if (containsConfig(configName)) {
        QVariantMap oldParams = m_configs[configName].toMap();
        QVariantMap newParams = oldParams;
        QVariantMap changedParams;
        
        // 批量更新参数
        for (auto it = configParams.constBegin(); it != configParams.constEnd(); ++it) {
            const QString &paramName = it.key();
            const QVariant &value = it.value();
            
            if (!oldParams.contains(paramName) || oldParams[paramName] != value) {
                newParams[paramName] = value;
                changedParams[paramName] = value;
            }
        }
        
        // 更新配置
        m_configs[configName] = newParams;
        
        // 发射批量变更信号
        if (!changedParams.isEmpty()) {
            emit configParamsChanged(configName, changedParams);
        }
    }
}

/**
 * @brief 批量获取配置的参数
 * @param configName 配置名称（唯一标识）
 * @param paramNames 参数名称列表
 * @return 配置参数，键为参数名称
 */
QVariantMap ConfigManager::batchGetConfigParams(const QString &configName, const QStringList &paramNames) const
{
    QVariantMap result;
    
    if (containsConfig(configName)) {
        QVariantMap configParams = m_configs[configName].toMap();
        
        // 批量获取指定参数
        for (const QString &paramName : paramNames) {
            if (configParams.contains(paramName)) {
                result[paramName] = configParams[paramName];
            }
        }
    }
    
    return result;
}

// ========== 文件操作 ==========

/**
 * @brief 从文件加载配置
 * @param filePath 文件路径，为空则使用默认路径
 * @return 是否加载成功
 */
bool ConfigManager::loadConfig(const QString &filePath)
{
    QString configPath = filePath.isEmpty() ? m_configFilePath : filePath;
    QFile configFile(configPath);
    
    if (!configFile.exists()) {
        emit configLoaded(false);
        return false;
    }
    
    if (!configFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        emit configLoaded(false);
        return false;
    }
    
    QByteArray jsonData = configFile.readAll();
    configFile.close();
    
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonData);
    if (!jsonDoc.isObject()) {
        emit configLoaded(false);
        return false;
    }
    
    // 保存旧的默认配置
    QVariantMap oldDefaultConfig = getConfigParams(m_defaultConfigName);
    
    // 加载所有配置
    m_configs = jsonDoc.object().toVariantMap();
    
    // 确保默认配置存在
    if (!containsConfig(m_defaultConfigName)) {
        addConfig(m_defaultConfigName);
    }
    
    // 发射默认配置的变更信号
    QVariantMap newDefaultConfig = getConfigParams(m_defaultConfigName);
    if (oldDefaultConfig != newDefaultConfig) {
        emit configParamsChanged(m_defaultConfigName, newDefaultConfig);
    }
    
    emit configLoaded(true);
    return true;
}

/**
 * @brief 保存配置到文件
 * @param filePath 文件路径，为空则使用默认路径
 * @return 是否保存成功
 */
bool ConfigManager::saveConfig(const QString &filePath)
{
    QString configPath = filePath.isEmpty() ? m_configFilePath : filePath;
    QFile configFile(configPath);
    
    if (!configFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
        emit configSaved(false);
        return false;
    }
    
    QJsonDocument jsonDoc = QJsonDocument::fromVariant(m_configs);
    QByteArray jsonData = jsonDoc.toJson(QJsonDocument::Indented);
    
    qint64 bytesWritten = configFile.write(jsonData);
    configFile.close();
    
    bool success = (bytesWritten == jsonData.size());
    emit configSaved(success);
    return success;
}
